Skip to content

use dataVolumeTemplates to perform image-based provisioning#178

Merged
evgeni merged 7 commits intomasterfrom
datavolume
Feb 9, 2026
Merged

use dataVolumeTemplates to perform image-based provisioning#178
evgeni merged 7 commits intomasterfrom
datavolume

Conversation

@evgeni
Copy link
Member

@evgeni evgeni commented Jan 22, 2026

The current code uses containerDisk for image-based provisioning, but this results in an ephemeral disk being created on the fly, which is probably not what most users want.
This PR changes it to use a dataVolume, created using a dataVolumeTemplate (see https://kubevirt.io/user-guide/storage/disks_and_volumes/#datavolume).

While working on this, I realized that the current UI doesn't give a way to configure the resulting (root) volume when using image-based provisioning. So this PR also changes this flow a bit: a "bootable" volume needs to be configured, the details of that volume (capacity, storage class) are used for the dataVolumeTempalte created one (previously, creating a "bootable" volume while doing image-based provisioning would result in an error).

Test notes:

  • You'll need an DataVolume in OpenShift that you can use for copying. I was using openshift-virtualization-os-images/centos-stream9-amd64 on our CNV cluster, you can see a list of available ones with oc get datasources -n openshift-virtualization-os-images

Dependencies:

@evgeni evgeni force-pushed the datavolume branch 3 times, most recently from 3d37370 to 0421ebb Compare January 22, 2026 10:38
@evgeni evgeni force-pushed the datavolume branch 4 times, most recently from 62ecc15 to d40037b Compare January 23, 2026 07:59
@evgeni evgeni marked this pull request as ready for review January 23, 2026 09:28
@evgeni evgeni changed the title use dataVolumeTemplates to create image based hosts use dataVolumeTemplates to perform image-based provisioning Jan 23, 2026
@evgeni evgeni force-pushed the datavolume branch 2 times, most recently from 8ecafc0 to 5e35b8e Compare January 23, 2026 11:01
@stejskalleos stejskalleos self-assigned this Jan 28, 2026
@evgeni evgeni force-pushed the datavolume branch 2 times, most recently from 29de397 to 3d8f7e2 Compare January 29, 2026 09:08
record.create_vm({ :name => "test", :provision_method => 'image', :image_id => "default/template", :volumes_attributes => { "0" => { :capacity => "10", :bootable => "true" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
end

test "raises an error for image based provisioning with only an extra data volume" do
Copy link
Member Author

@evgeni evgeni Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this duplicates the "create_vm image based without additional volumes should fail" test below, so probably can be dropped now? (in a previous iteration of this PR this checked that a VM actually gets created correctly)

record.create_vm({ :name => "test", :volumes_attributes => { 0 => { :capacity => "5" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
end

test "raises an error for image based provisioning without an explicit boot volume" do
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this duplicates the "create_vm image based without additional volumes should fail" test below, so probably can be dropped now? (in a previous iteration of this PR this checked that a VM actually gets created correctly)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still a case? Can't find the create_vm image based without additional volumes should fail test

Copy link
Member Author

@evgeni evgeni Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

@shubhamsg199 shubhamsg199 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and works as expected. Able to create a host via foreman and dataVolumeTemplates is used to create the said DataVolume

record.create_vm({ :name => "test", :volumes_attributes => { 0 => { :capacity => "5" } }, :interfaces_attributes => { "0" => { "cni_provider" => "multus", "network" => "default/network" } } })
end

test "raises an error for image based provisioning without an explicit boot volume" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still a case? Can't find the create_vm image based without additional volumes should fail test

end

def add_volume_for_image_provision(options)
def add_volume_template_for_image_provision(options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the UI, when provisioning a host from an image, I need to add a bootable storage disk.
But that's something users don't know they are required to do.

Should we include it in the UI as a tooltip or at least mention it in the docs?
cc @jafiala

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is that solved in other CRs? it's not like we're the first one to require a target when deploying something? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

answering myself, vm_instance_defaults:

def vm_instance_defaults
{
:memory => 1024.megabytes.to_s,
:cpu_cores => '1'
}
end

Copy link
Member Author

@evgeni evgeni Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding :volumes => [new_volume].compact (stolen from the libvirt CR) here gives me:
image

No idea if setting size and boot flags by default is a good idea here as I have no knowledge where else vm_instance_defaults are used

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would that make the storage class default for both image based and non image based right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other CRs taking example of VMware, the volume section is already added with some default size and other default fields

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it would make the storage section be populated with one default volume for both provisioning methods, but it's also kinda right -- you can't provision without a (target) disk after all.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agree , we need at least one disk to be selected but also which storage class to be setted as default is a concern , as there is also a way to define default storage class in kuberneties/openshift https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/ and we can also check if a storage class is default or not in https://github.com/fog/fog-kubevirt/blob/master/lib/fog/kubevirt/compute/models/storageclass.rb#L33 while parsing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the "empty" volume for now, we can enhance later

raise ::Foreman::Exception.new _('VM should be created based on an image') unless image

verify_booting_from_image_is_possible(options[:volumes_attributes])
namespace, name = image.split('/', 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When creating the image, I believe we should update the tooltip to include an option to specify whether to include a namespace. Also, if the token works in other workspaces that are not configured on the compute resource, it works there as well. This edge case could be mentioned in the docs only.

The API help text will need to be updated as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the help in the UI.

The API is not altered by the plugin (as the field comes from core), so can't be done there.

@evgeni
Copy link
Member Author

evgeni commented Feb 3, 2026

Copy link
Contributor

@stejskalleos stejskalleos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments have been addressed, code looks good, but I haven't tested it with the latest changes.

@shubhamsg199, once you confirm the functionality, we can merge.

Copy link

@shubhamsg199 shubhamsg199 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

@evgeni evgeni merged commit 4a501b4 into master Feb 9, 2026
7 of 9 checks passed
@evgeni evgeni deleted the datavolume branch February 9, 2026 12:03
@evgeni evgeni mentioned this pull request Feb 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants